package com.fuyao.cloud.common.biz.service;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.common.biz.dto.PageQuery;
import com.fuyao.cloud.common.biz.entity.AuditableEntity;
import com.fuyao.cloud.common.core.model.FyUser;
import com.fuyao.cloud.common.security.service.CloudUser;
import com.fuyao.cloud.common.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Constructor;


/**
 * @author lyhills
 * @Description
 * @date 2023/6/9 11:44
 * @Version 1.0
 */
@Slf4j
public abstract class FyBaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements FyBaseService<T> {

    @SuppressWarnings("unchecked")
    @Override
    public T create() {
        Constructor<?>[] constructors = this.entityClass.getDeclaredConstructors();
        T entiry = null;
        if (constructors.length > 0) {
            try {
                entiry = (T) constructors[0].newInstance();
            } catch (Exception e) {
                log.warn(e.getMessage(), e);
            }
        }
        onCreated(entiry);
        return entiry;
    }

    @Override
    public void onCreated(T entity) {
        if (entity != null) {
            if (entity instanceof AuditableEntity) {
                AuditableEntity auditableEntity=  ((AuditableEntity) entity);
                auditableEntity.setUnid(IdUtil.simpleUUID());
                CloudUser user = SecurityUtils.getUser();
                auditableEntity.setCreateId(user.getId());
                auditableEntity.setCreateBy(user.getNickname());
                auditableEntity.setDeptId(user.getDeptId());
                auditableEntity.setDeptFullName(user.getFullName());
            }
        }
    }

    @Transactional
    @Override
    public boolean save(T entity) {
        beforeSave(entity);
        boolean save = super.save(entity);
        afterSave(entity);
        return save;
    }

    @Transactional
    @Override
    public boolean updateById(T entity) {
        beforeSave(entity);
        boolean update = super.updateById(entity);
        afterSave(entity);
        return update;
    }

    protected void beforeSave(T entity) {

    }

    protected void afterSave(T entity) {

    }

    @Override
    public Page<T> getPage(PageQuery<T> pageQuery) {
        return getBaseMapper().selectPage(pageQuery.getPage(), Wrappers.query(pageQuery.getExample()));
    }

    protected CloudUser getCloudUser() {
        return SecurityUtils.getUser();
    }

    protected FyUser getFyUser() {
        return getCloudUser().toFyUser();
    }
}
